package de.mrapp.tabswitcher.view;

import de.mrapp.tabswitcher.*;
import de.mrapp.tabswitcher.drawable.TabSwitcherDrawable;
import de.mrapp.tabswitcher.util.DimensionUtil;
import de.mrapp.tabswitcher.util.PixelUtil;
import de.mrapp.util.Condition;
import ohos.agp.components.*;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.global.resource.Resource;

/**
 * An image button, which allows to display the number of tabs, which are currently contained by a
 * {@link TabSwitcher} by using a {@link TabSwitcherDrawable}. It must be registered at a {@link
 * TabSwitcher} instance in order to keep the displayed count up to date. It therefore implements
 * the interface {@link TabSwitcherListener}.
 */
public class TabSwitcherButton extends StackLayout implements TabSwitcherListener {
    /**
     * The default text size of the displayed label in pixels.
     */
    private int textSizeNormal;
    /**
     * The text size of the displayed label, which is used when displaying a value greater than 99,
     * in pixels.
     */
    private int textSizeSmall;
    /**
     * The currently displayed label.
     */
    private String label = "0";

    private Image image;

    private Text text;

    private TabSwitcherDrawable drawable;

    /**
     * Creates a new image button, which allows to display the number of tabs, which are currently
     * contained by a {@link TabSwitcher}.
     *
     * @param context The context, which should be used by the view, as an instance of the class {@link
     *                Context}. The context may not be null
     */
    public TabSwitcherButton(final Context context) {
        this(context, null);
    }

    /**
     * Creates a new image button, which allows to display the number of tabs, which are currently
     * contained by a {@link TabSwitcher}.
     *
     * @param context      The context, which should be used by the view, as an instance of the class {@link
     *                     Context}. The context may not be null
     * @param attributeSet The attribute set, the view's attributes should be obtained from, as an instance of
     *                     the type {@link AttrSet} or null, if no attributes should be obtained
     */
    public TabSwitcherButton(final Context context,
                             final AttrSet attributeSet) {
        this(context, attributeSet, "");
    }

    /**
     * Creates a new image button, which allows to display the number of tabs, which are currently
     * contained by a {@link TabSwitcher}.
     *
     * @param context      The context, which should be used by the view, as an instance of the class {@link
     *                     Context}. The context may not be null
     * @param attributeSet The attribute set, the view's attributes should be obtained from, as an instance of
     *                     the type {@link AttrSet} or null, if no attributes should be obtained
     * @param defaultStyle The default style to apply to this view. If 0, no style will be applied (beyond what
     *                     is included in the theme). This may either be an attribute resource, whose value will
     *                     be retrieved from the current theme, or an explicit style resource
     */
    public TabSwitcherButton(final Context context,
                             final AttrSet attributeSet,
                             final String defaultStyle) {
        super(context, attributeSet, defaultStyle);
        initialize(context);
        initImage();
        initText();
    }

    private void initialize(Context context) {
        setClickable(true);
        setFocusable(FOCUS_ENABLE);
        textSizeNormal = (int) PixelUtil.fp2px(DimensionUtil.parseDimension(context.getString(ResourceTable.String_tab_switcher_drawable_font_size_normal)));
        textSizeSmall = (int) PixelUtil.fp2px(DimensionUtil.parseDimension(context.getString(ResourceTable.String_tab_switcher_drawable_font_size_small)));
        label = Integer.toString(0);
    }

    private void initImage() {
        image = new Image(getContext());

        Resource resource = convertRes(getContext(), ResourceTable.Media_tab_switcher_drawable_background);
        //The drawable, which is used by the image button.
        drawable = new TabSwitcherDrawable(getContext(), resource);
        image.setImageElement(drawable);
        StackLayout.LayoutConfig imageParams = new LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, StackLayout.LayoutConfig.MATCH_PARENT);
        imageParams.alignment = TextAlignment.CENTER;
        addComponent(image, imageParams);
    }

    public void setButtonColor(float matrix, Color textColor) {
        if (drawable != null) {
            drawable.setColorMatrix(matrix);
        }
        if (text != null) {
            text.setTextColor(textColor);
        }

    }

    private void initText() {
        text = new Text(getContext());
        text.setTextColor(Color.DKGRAY);
        text.setTextSize(textSizeNormal);
        text.setFont(Font.SANS_SERIF);
        text.setText(label);
        text.setTextAlignment(TextAlignment.CENTER);

        StackLayout.LayoutConfig textParams = new LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, StackLayout.LayoutConfig.MATCH_PARENT);
        textParams.alignment = TextAlignment.CENTER;
        addComponent(text, textParams);
    }


    private Resource convertRes(Context mContext, int drawableRes) {
        Resource resource = null;
        try {
            resource = mContext.getResourceManager().getResource(drawableRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resource;
    }

    /**
     * Updates the image button to display a specific value.
     *
     * @param count The value, which should be displayed, as an {@link Integer} value. The value must be
     *              at least 0
     */
    public final void setCount(final int count) {
        Condition.INSTANCE.ensureAtLeast(count, 0, "The count must be at least 0");
        label = Integer.toString(count);
        text.setText(label);
        if (label.length() > 2) {
            label = "99+";
            text.setTextSize(textSizeSmall);
        } else {
            text.setTextSize(textSizeNormal);
        }
    }


    @Override
    public void onSwitcherShown(TabSwitcher tabSwitcher) {
    }

    @Override
    public void onSwitcherHidden(TabSwitcher tabSwitcher) {
    }

    @Override
    public void onSelectionChanged(TabSwitcher tabSwitcher, int selectedTabIndex, Tab selectedTab) {
    }

    @Override
    public void onTabAdded(TabSwitcher tabSwitcher, int index, Tab tab, Animation animation) {
        setCount(tabSwitcher.getCount());
    }

    @Override
    public void onTabRemoved(TabSwitcher tabSwitcher, int index, Tab tab, Animation animation) {
        setCount(tabSwitcher.getCount());
    }

    @Override
    public void onAllTabsRemoved(TabSwitcher tabSwitcher, Tab[] tabs, Animation animation) {
        setCount(tabSwitcher.getCount());
    }
}
